;
; vmpaste.asm
;

include vmbdoor.inc

; enable x486 instructions, but use 16 bit segment
.486
option segment:use16

; code segment
codes	segment para use16 public 'CODE'
codes	ends

; data segment
datas	segment byte use16 public 'DATA'
BDOOR_MAGIC	dword  	VMWARE_MAGIC
BDOOR_PORT  	word	VMWARE_PORT
MSG_DISABLED	byte	'Copy & paste is disabled.', CR, LF
MSG_VMNG	byte	'Not running inside VMware.', CR, LF
datas	ends

main	group codes,datas

codes	segment
; for tiny memory model (.com), all seg is the same
assume	cs:main,ds:main,es:main,ss:main
org	100h
entry:
check_vm	proc near
	; Check if we are running inside VMware
	xor 	ecx,ecx
	mov 	cl, VMCMD_GET_VERSION
	call	backdoor

	cmp	ebx,[BDOOR_MAGIC]
	jne	not_in_vm

	; Check if copy & paste is enabled
	mov	cl, VMCMD_GET_SETTING
	call	backdoor

	and	eax, VMPREF_COPY_PASTE
	jz	disabled
check_vm	endp

;************************************************
; paste operation
;************************************************
do_paste	proc near
	; First get data length
	xor	ecx, ecx
	mov	cl, VMCMD_GET_CLIPLEN
	call	backdoor

	and	eax, eax			; check length
	jz	terminate			; no clipboard data

next_data:
	push	eax

	xor	ecx, ecx
	mov	cl, VMCMD_GET_CLIPDATA
	call	backdoor

	mov	edx, eax			; store returned data

	call	put_char			; put first char

	shr	edx, 8				; put second char
	call	put_char

	shr	edx, 8				; put third char
	call	put_char

	shr	edx, 8				; put fourth char
	call	put_char

	pop	eax				; retrieve length
	cmp	eax, 4				; more data?
	jbe	terminate			; no.  return to DOS

	sub	eax, 4
	jmp	next_data
do_paste	endp

;************************************************
; terminate routines
;************************************************

disabled:
	mov	bp, offset MSG_DISABLED		; disabled message
	mov	cx, 27				; length
	jmp	print_msg

not_in_vm:
	mov	bp, offset MSG_VMNG		; not in VM message
	mov	cx, 28				; length

print_msg:
	push	cx

	; get current curosr position
	mov 	ah, 03h
	xor 	bh, bh
	int 	10h
	; returned to DH:DL

	; get attribute at current cursor position
	mov	ah, 08h
	xor	bh, bh				; page number
	int	10h				; Video function call

	mov	bl, ah				; returned attribute
	pop	cx				; message length

	mov 	ah, 13h				; write function 
	mov	al, 1				; update cursor position
	int	10h				; Video function call
	xor	al, al				; return code = 0

terminate:					; Now Return to DOS
	mov	ah, 4ch
	int	21h
	; this function call never returnes

;************************************************
; executes vmware backdoor i/o
;************************************************
backdoor	proc near
        mov	eax, [BDOOR_MAGIC]
        mov	dx, [BDOOR_PORT]
        in	eax, dx
	ret
backdoor	endp

;************************************************
; write a character to stdout
;************************************************
; if the character is 0, terminate program
; if the character is LF, supply CR
put_char	proc near
	and	dl, dl
	jz	terminate

	mov	ah, 02h				; STDOUT output function

	cmp	dl, LF
	jne	normal_char

	; put CR char first
	mov	bl, dl				; store LF char
	mov	dl, CR
	int	21h
	mov	dl, bl				; restore LF char

normal_char:
	int	21h
	ret
put_char	endp

codes	ends
end	entry
; end of file
